{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<table align=\"left\">\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/gimseng/99-ML-Learning-Projects/blob/master/002/exercise/linear_regression.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
    "  </td>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Hi - Welcome to the Linear Regression exercise\n",
    "\n",
    "## The first half of this notebook is meant for data preprocessing, it's not mandatory but heavily encouraged to go over them and understand what is going on.\n",
    "\n",
    "## The main task of the assignment is in the second half of the notebook\n",
    "\n",
    "### Run cells below which import all required libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import sklearn, sklearn.model_selection\n",
    "import matplotlib as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The cell below retrieves the data and splits it into train_x, train_y, valid_x, valid_y, test_x, test_y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "train size: 876, valid size: 292, test size: 292\n"
     ]
    }
   ],
   "source": [
    "# pick how big the validation/test portion of the data is, currently set to 20% validation, 20% test, and 60% train\n",
    "valid_size = 0.2\n",
    "test_size = 0.2\n",
    "\n",
    "# load the data from the .csv file\n",
    "github_url = 'https://raw.githubusercontent.com/gimseng/99-ML-Learning-Projects/'\n",
    "data_source = 'master/002/data/housing_prices.csv'\n",
    "data = pd.read_csv(github_url+data_source)\n",
    "# Drop the 'Id' column since it is a useless feature\n",
    "data = data.drop(columns='Id')\n",
    "\n",
    "def train_valid_test_split(data, valid_size, test_size):\n",
    "    # split into train and test\n",
    "    train, test = sklearn.model_selection.train_test_split(data, test_size=test_size)\n",
    "    # further split train into train and validation. (valid_size needs to be recalculated to properly split train)\n",
    "    valid_size = valid_size/(1-test_size)\n",
    "    train, valid = sklearn.model_selection.train_test_split(train, test_size=valid_size)\n",
    "    return train, valid, test\n",
    "\n",
    "train, valid, test = train_valid_test_split(data, valid_size, test_size)\n",
    "train_x, train_y = train.iloc[:, :-1], train.iloc[:, -1:]\n",
    "valid_x, valid_y = valid.iloc[:, :-1], valid.iloc[:, -1:]\n",
    "test_x, test_y = test.iloc[:, :-1], test.iloc[:, -1:]\n",
    "\n",
    "print(f'train size: {len(train_x)}, valid size: {len(valid_x)}, test size: {len(test_x)}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The cell below helps us view a few of our data points and also view how the selling price varies for different features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>MSSubClass</th>\n",
       "      <th>MSZoning</th>\n",
       "      <th>LotFrontage</th>\n",
       "      <th>LotArea</th>\n",
       "      <th>Street</th>\n",
       "      <th>Alley</th>\n",
       "      <th>LotShape</th>\n",
       "      <th>LandContour</th>\n",
       "      <th>Utilities</th>\n",
       "      <th>LotConfig</th>\n",
       "      <th>...</th>\n",
       "      <th>PoolArea</th>\n",
       "      <th>PoolQC</th>\n",
       "      <th>Fence</th>\n",
       "      <th>MiscFeature</th>\n",
       "      <th>MiscVal</th>\n",
       "      <th>MoSold</th>\n",
       "      <th>YrSold</th>\n",
       "      <th>SaleType</th>\n",
       "      <th>SaleCondition</th>\n",
       "      <th>SalePrice</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>60</td>\n",
       "      <td>RL</td>\n",
       "      <td>65.0</td>\n",
       "      <td>8450</td>\n",
       "      <td>Pave</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Reg</td>\n",
       "      <td>Lvl</td>\n",
       "      <td>AllPub</td>\n",
       "      <td>Inside</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>2008</td>\n",
       "      <td>WD</td>\n",
       "      <td>Normal</td>\n",
       "      <td>208500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>20</td>\n",
       "      <td>RL</td>\n",
       "      <td>80.0</td>\n",
       "      <td>9600</td>\n",
       "      <td>Pave</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Reg</td>\n",
       "      <td>Lvl</td>\n",
       "      <td>AllPub</td>\n",
       "      <td>FR2</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>5</td>\n",
       "      <td>2007</td>\n",
       "      <td>WD</td>\n",
       "      <td>Normal</td>\n",
       "      <td>181500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>60</td>\n",
       "      <td>RL</td>\n",
       "      <td>68.0</td>\n",
       "      <td>11250</td>\n",
       "      <td>Pave</td>\n",
       "      <td>NaN</td>\n",
       "      <td>IR1</td>\n",
       "      <td>Lvl</td>\n",
       "      <td>AllPub</td>\n",
       "      <td>Inside</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>9</td>\n",
       "      <td>2008</td>\n",
       "      <td>WD</td>\n",
       "      <td>Normal</td>\n",
       "      <td>223500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>70</td>\n",
       "      <td>RL</td>\n",
       "      <td>60.0</td>\n",
       "      <td>9550</td>\n",
       "      <td>Pave</td>\n",
       "      <td>NaN</td>\n",
       "      <td>IR1</td>\n",
       "      <td>Lvl</td>\n",
       "      <td>AllPub</td>\n",
       "      <td>Corner</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>2006</td>\n",
       "      <td>WD</td>\n",
       "      <td>Abnorml</td>\n",
       "      <td>140000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>60</td>\n",
       "      <td>RL</td>\n",
       "      <td>84.0</td>\n",
       "      <td>14260</td>\n",
       "      <td>Pave</td>\n",
       "      <td>NaN</td>\n",
       "      <td>IR1</td>\n",
       "      <td>Lvl</td>\n",
       "      <td>AllPub</td>\n",
       "      <td>FR2</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>12</td>\n",
       "      <td>2008</td>\n",
       "      <td>WD</td>\n",
       "      <td>Normal</td>\n",
       "      <td>250000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 80 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   MSSubClass MSZoning  LotFrontage  LotArea Street Alley LotShape  \\\n",
       "0          60       RL         65.0     8450   Pave   NaN      Reg   \n",
       "1          20       RL         80.0     9600   Pave   NaN      Reg   \n",
       "2          60       RL         68.0    11250   Pave   NaN      IR1   \n",
       "3          70       RL         60.0     9550   Pave   NaN      IR1   \n",
       "4          60       RL         84.0    14260   Pave   NaN      IR1   \n",
       "\n",
       "  LandContour Utilities LotConfig  ... PoolArea PoolQC Fence MiscFeature  \\\n",
       "0         Lvl    AllPub    Inside  ...        0    NaN   NaN         NaN   \n",
       "1         Lvl    AllPub       FR2  ...        0    NaN   NaN         NaN   \n",
       "2         Lvl    AllPub    Inside  ...        0    NaN   NaN         NaN   \n",
       "3         Lvl    AllPub    Corner  ...        0    NaN   NaN         NaN   \n",
       "4         Lvl    AllPub       FR2  ...        0    NaN   NaN         NaN   \n",
       "\n",
       "  MiscVal MoSold  YrSold  SaleType  SaleCondition  SalePrice  \n",
       "0       0      2    2008        WD         Normal     208500  \n",
       "1       0      5    2007        WD         Normal     181500  \n",
       "2       0      9    2008        WD         Normal     223500  \n",
       "3       0      2    2006        WD        Abnorml     140000  \n",
       "4       0     12    2008        WD         Normal     250000  \n",
       "\n",
       "[5 rows x 80 columns]"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<AxesSubplot:xlabel='Garage car room', ylabel='Sale Price'>"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAGpCAYAAABcR4WXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAACqm0lEQVR4nOz9eXxkZ3nn/X/u2qu0b71vdnd7aRtswBgHbAIYbCchwcnAg7PhZJw4w8BMtnkmkHlmSGD8S5iZhBkmgQDBwZBMsAPJ4LA5xhiwjbHdBi94abfavbe6W/tWe9X9++OcU6qSSqUqqaq01Pf9eunV0q06R0eyJJ+6dF3f21hrERERERERERERaSbfal+AiIiIiIiIiIi0HhWlRERERERERESk6VSUEhERERERERGRplNRSkREREREREREmk5FKRERERERERERabrAal/AWtHf32/37Nmz2pchIiIiDfTkk0+OWGsHVvs6ZI7uwURERDa2SvdfKkq59uzZw8GDB1f7MkRERKSBjDHHV/sapJTuwURERDa2SvdfGt8TEREREREREZGmU1FKRERERERERESaTkUpERERERERERFpOhWlRERERERERESk6VSUEhERERERERGRplNRSkREREREREREmq7hRSljjN8Y8yNjzFfdt3uNMfcbYw67//YUPfaDxphBY8whY8yNReuvMcY8677v48YY466HjTF3u+uPGWP2FB1zq/sxDhtjbm305ykiIiIiIiIiItVrRqfUbwMvFL39AeABa+1+4AH3bYwxB4BbgMuAm4BPGGP87jGfBG4H9rsvN7nrtwHj1tp9wMeAj7rn6gU+BLwOuBr4UHHxS0REREREREREVldDi1LGmB3AzwB/XbT8DuAu9/W7gJuL1r9orU1Za48Cg8DVxpitQKe19lFrrQU+P+8Y71xfAq53u6huBO631o5Za8eB+5krZImIiIiIiIiIyCprdKfU/wT+I5AvWttsrR0CcP/d5K5vB04WPe6Uu7bdfX3+eskx1tosMAn0VThXCWPM7caYg8aYg8PDw8v49EREREREREREZDkaVpQyxrwdOG+tfbLaQ8qs2Qrryz1mbsHaT1trr7LWXjUwMFDlZYqIiIiIiIiIyEo1slPqDcDPGWOOAV8E3mKM+VvgnDuSh/vveffxp4CdRcfvAM646zvKrJccY4wJAF3AWIVziYiIiIiIiIjIGtCwopS19oPW2h3W2j04Aebfttb+CnAv4O2GdyvwFff1e4Fb3B31LsAJNH/cHfGbNsZc4+ZFvWfeMd653ul+DAvcB9xgjOlxA85vcNdERERERERERGQNCKzCx/xT4B5jzG3ACeBdANba54wx9wDPA1ngfdbanHvMe4HPAVHgG+4LwGeBLxhjBnE6pG5xzzVmjPkI8IT7uA9ba8ca/YmJiIiIiIiIiEh1jNNYJFdddZU9ePDgal+GiIhIy8rm8hw+P8PWrgjdsVBDPoYx5klr7VUNObksi+7BRERENrZK91+N3n1PREREpCoTiQw/9b8e4t6nFQMpIiIi0gpWY3xPREREZIFMLg9AyK+/mYmIiHj2fOBrq30JdXPsT39mtS9B1hjd9YmIiMiakMk6kQJBFaVEREREWoLu+kRERGRNSLudUsGAbk9EREREWoHu+kRERGRNmBvfM6t8JSIiIiLSDCpKiYiIyJqQzrqdUhrfExEREWkJuusTERGRNcHrlFJRSkRERKQ16K5PRERE1gQvUyqkTCkRERGRlqC7PhEREVkTMjntviciIiLSSnTXJyIiImtCJusFnev2RERERKQV6K5PRERE1oRCplRAu++thDEmYox53BjztDHmOWPMH7vrvcaY+40xh91/e4qO+aAxZtAYc8gYc2PR+muMMc+67/u4Mca462FjzN3u+mPGmD1Fx9zqfozDxphbm/ipi4iIyDqjopSIiIisCWkFnddLCniLtfYK4ErgJmPMNcAHgAestfuBB9y3McYcAG4BLgNuAj5hjPG75/okcDuw3325yV2/DRi31u4DPgZ81D1XL/Ah4HXA1cCHiotfIiIiIsV01yciIiJrQlrje3VhHTPum0H3xQLvAO5y1+8CbnZffwfwRWttylp7FBgErjbGbAU6rbWPWmst8Pl5x3jn+hJwvdtFdSNwv7V2zFo7DtzPXCFLREREpITu+kRERGRN8ILOtfveyhlj/MaYp4DzOEWix4DN1tohAPffTe7DtwMniw4/5a5td1+fv15yjLU2C0wCfRXONf/6bjfGHDTGHBweHl7BZyoiIiLrme76REREZE3IaHyvbqy1OWvtlcAOnK6nyys8vFyIl62wvtxjiq/v09baq6y1Vw0MDFS4NBEREdnIdNcnIiIia8JcUUpB5/VirZ0AvoMzQnfOHcnD/fe8+7BTwM6iw3YAZ9z1HWXWS44xxgSALmCswrlEREREFlBRSkRERNYEBZ3XhzFmwBjT7b4eBd4KvAjcC3i74d0KfMV9/V7gFndHvQtwAs0fd0f8po0x17h5Ue+Zd4x3rncC33Zzp+4DbjDG9LgB5ze4ayIiIiILBFb7AkRERERgLuhcRakV2wrc5e6g5wPusdZ+1RjzKHCPMeY24ATwLgBr7XPGmHuA54Es8D5rbc4913uBzwFR4BvuC8BngS8YYwZxOqRucc81Zoz5CPCE+7gPW2vHGvrZioiIyLqlopSIiIisCZlcHr/P4PdpfG8lrLXPAK8qsz4KXL/IMXcAd5RZPwgsyKOy1iZxi1pl3ncncGdtVy0iIiKtSH+KFBERkTUhk7PKkxIRERFpISpKiYiIyJqQzuYJaXRPREREpGXozk9ERETWhEwuTyigWxMRERGRVqE7PxEREVkTMrm8Qs5FREREWoju/ERERGRNcDKldGsiIiIi0ip05yciIiJrQjqbV9C5iIiISAtRUUpERETWhLTG90RERERaiu78REREZE3I5PKEFXQuIiIi0jJ05yciIiJrgoLORURERFqL7vxERERkTchkFXQuIiIi0kp05yciIiJrQjqXJ6jxPREREZGWoTs/ERERWRPS2Twh7b4nIiIi0jJUlBIREZE1QZlSIiIiIq1Fd34iIiKyJqgoJSIiItJadOcnIiIia0ImZwkpU0pERESkZejOT0RERNaEtDqlRERERFqK7vxERERkTcjkFHQuIiIi0kpUlBIREZE1IZ1Vp5SIiIhIK9Gdn4iIiKwJmVyeoDKlRERERFqG7vxERERk1VlryeSsOqVEREREWoju/ERERGTVZXIWgLA6pURERERahu78REREZNVlcnkAggo6FxEREWkZKkqJiIjIqpsrSunWRERERKRV6M5PREREVl06q6KUiIiISKvRnZ+IiIisurTbKRVSUUpERESkZejOT0RERFadF3QeDChTSkRERKRVqCglIiIiqy5T6JTyr/KViIiIiEizqCglIiIiq24uU0qdUiIiIiKtomFFKWNMxBjzuDHmaWPMc8aYP3bX/8gYc9oY85T78tNFx3zQGDNojDlkjLmxaP01xphn3fd93Bhj3PWwMeZud/0xY8yeomNuNcYcdl9ubdTnKSIiIitX2H0voL+XiYiIiLSK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\n",
      "text/plain": [
       "<Figure size 1440x504 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axes = plt.subplots(nrows=1, ncols=2)\n",
    "fig=(20,7)\n",
    "data.groupby('YearBuilt').mean()['SalePrice'].plot(ylabel='Sale Price',xlabel='Year Built',ax=axes[0],figsize=fig)\n",
    "data.groupby('GarageCars').mean()['SalePrice'].plot(kind='bar',ylabel='Sale Price',xlabel='Garage car room',ax=axes[1],figsize=fig)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The cell below scales the numeric features using a min_max_scaler (scales them between 0 and 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "numeric_columns = train_x.select_dtypes(include='number').columns\n",
    "# scaler = sklearn.preprocessing.MinMaxScaler()\n",
    "# scaler = sklearn.preprocessing.KBinsDiscretizer(n_bins=10, encode='ordinal')\n",
    "scaler = sklearn.preprocessing.StandardScaler()\n",
    "# train on concatenation of train and validation\n",
    "scaler.fit(pd.concat((train_x[numeric_columns], valid_x[numeric_columns])))\n",
    "# apply on all data\n",
    "train_x[numeric_columns] = scaler.transform(train_x[numeric_columns])\n",
    "valid_x[numeric_columns] = scaler.transform(valid_x[numeric_columns])\n",
    "test_x[numeric_columns] = scaler.transform(test_x[numeric_columns])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The cell below one-hot encodes the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_dummies_column_keys(dataFrames):\n",
    "    '''returns a column list of get dummies for concatenated dataframes'''\n",
    "    return pd.get_dummies(pd.concat(dataFrames)).columns.tolist()\n",
    "\n",
    "def get_dummies_using_keys(dataFrame, column_keys):\n",
    "    '''returns get dummies result with columns matching column_keys'''\n",
    "    result = pd.get_dummies(dataFrame)\n",
    "    result = result.reindex(columns=column_keys).fillna(0.00)\n",
    "    return result\n",
    "\n",
    "# get the keys for the concatenation of all datasets \n",
    "column_keys = get_dummies_column_keys((train_x, valid_x, test_x))\n",
    "train_x = get_dummies_using_keys(train_x, column_keys)\n",
    "valid_x = get_dummies_using_keys(valid_x, column_keys)\n",
    "test_x = get_dummies_using_keys(test_x, column_keys)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The cell below appends a '1' to all rows by adding a 'Bias' feature with the value of 1 for all rows<br/> This is to simulate a bias without adding any bias functionality to the Linear Regression algorithm "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_x['Bias'] = 1\n",
    "valid_x['Bias'] = 1\n",
    "test_x['Bias'] = 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### This last cell gets the numpy arrays that we will work on from the panda dataframes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# store the dataframes in df_* variables\n",
    "df_train_x, df_train_y = train_x, train_y\n",
    "df_valid_x, df_valid_y = valid_x, valid_y\n",
    "df_test_x, df_test_y = test_x, test_y\n",
    "\n",
    "# store the numpy arrays in the regular variables\n",
    "train_x, train_y = train_x.values, train_y.values\n",
    "valid_x, valid_y = valid_x.values, valid_y.values\n",
    "test_x, test_y = test_x.values, test_y.values"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Proceed with any data analysis in the next cell\n",
    "\n",
    "## (Optional but encouraged)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# This is the main task of the excercise\n",
    "\n",
    "## You need to implement the following functions which <br/> implements Linear Regression and all it's required functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The first major function is the 'predict' function <br/> Remember the Linear Regression equation is\n",
    "$$\\hat{Y} = w_0 + w_1 x_1 + w_2 x_2 + ... + w_m x_m$$\n",
    "\n",
    "### hint: try to implement a 'vectorized' version by using a matrix multiplication<br/> which will massively increase performance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    " def predict(w, x):\n",
    "    '''\n",
    "    Return the linear regression prediction from the weights and input features\n",
    "    Args:\n",
    "        w: The weight vector, shape: (features, 1)\n",
    "        x: The input data, shape: (num_samples, features)\n",
    "    Returns:\n",
    "        The prediction of the model, shape: (num_samples, 1)\n",
    "    '''\n",
    "    ### YOUR CODE HERE\n",
    "    raise NotImplementedError\n",
    "\n",
    "def init_weights(x):\n",
    "    '''\n",
    "    Initialize the weights vector, the data is passed in to know how many weights you need\n",
    "    Args:\n",
    "        x: The input data, shape: (num_samples, features)\n",
    "    Returns:\n",
    "        The initial weight vector of zeros, shape: (features, 1)\n",
    "    '''\n",
    "    ### YOUR CODE HERE\n",
    "    raise NotImplementedError"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Next you have to implement the Mean Squared Error Loss calculation by applying the following formula \n",
    "$$LOSS(W)=\\frac{1}{2n} \\sum_{i=1}^{n} (\\hat{y}_i-y_i)^2$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def loss(y_hat, y):\n",
    "    '''\n",
    "    Calculate the Mean Squared Error based on the y_hat (the predicted value) and y (the true values)\n",
    "    Args:\n",
    "        y_hat: the predicted values of the input, shape: (num_samples, 1)\n",
    "        y: the true values of the input, shape: (num_samples, 1)\n",
    "    Returns:\n",
    "        Mean Squared Error, shape: Scaler\n",
    "    '''\n",
    "    ### YOUR CODE HERE\n",
    "    raise NotImplementedError"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Next you have to implement the gradient calculation for the weights accoarding to the formula\n",
    "\n",
    "$$\\frac{\\partial LOSS(W)}{\\partial W_j} \n",
    "= \\frac{\\partial}{\\partial W_j} \\frac{1}{2n} \\sum_{i=1}^{n} (\\hat{y}_i-y_i)^2\n",
    "= \\frac{1}{2} \\sum_{i=1}^{n} ((\\hat{y}_i-y_i)*x_{i,j})$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "def get_gradient(w, x, y_hat, y):\n",
    "    '''\n",
    "    Get the gradient of the weights using the parameters passed \n",
    "    (Note: not all parameters passed have to be used)\n",
    "    Args:\n",
    "        w: The weight vector, shape: (features, 1)\n",
    "        x: The input data, shape: (num_samples, features)\n",
    "        y_hat: the predicted values of the input, shape: (num_samples, 1)\n",
    "        y: the true values of the input, shape: (num_samples, 1)\n",
    "    Returns:\n",
    "        The gradients of the weight vector, shape: (features, 1)\n",
    "    '''\n",
    "    ### YOUR CODE HERE\n",
    "    raise NotImplementedError"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Next you have to implement the gradient descent update for the weights according to the formula\n",
    "\n",
    "$$w_j:=w_j - \\alpha * \\frac{\\partial LOSS(W)}{\\partial W_j} $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_updated_weights(w, w_gradients, learning_rate):\n",
    "    '''\n",
    "    Calculate the new value of the weights after applying the gradient descent weight update rule \n",
    "    Args:\n",
    "        w: The weight vector, shape: (features, 1)\n",
    "        w_gradients: The gradients of the weight vector, shape: (features, 1)\n",
    "        learning_rate: The learning rate of the algorithm, shape: Scaler\n",
    "    Returns:\n",
    "        The updated value of the weights, shape: (features, 1)\n",
    "    '''\n",
    "    ### YOUR CODE HERE\n",
    "    raise NotImplementedError"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Finally implement the training loop, this should simply be<br/> a loop that calls the functions you implemented above"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train(epochs, x, y, learning_rate=1e-3, initial_weights=None):\n",
    "    '''\n",
    "    The main train loop for the algorithm. This performs the gradient update step 'epochs' times.\n",
    "    Args:\n",
    "        x: The input data, shape: (num_samples, features)\n",
    "        y: the true values of the input, shape: (num_samples, 1)\n",
    "        learning_rate: The learning rate of the algorithm, shape: Scaler\n",
    "        initial_weights: The initial weight to start training, this should be passed to continue training\n",
    "    Returns:\n",
    "        The final weight values after applying 'epochs' number of updates on 'initial_weights', shape: (features, 1)\n",
    "    '''\n",
    "    if initial_weights is None:\n",
    "        weight = init_weights(x)\n",
    "    else:\n",
    "        weight = initial_weights\n",
    "    \n",
    "    for epoch in range(epochs):\n",
    "        ### YOUR CODE HERE\n",
    "        raise NotImplementedError\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The cell below will run your code\n",
    "\n",
    "### After 200,000 epochs our results were the following: \n",
    "### Train loss: 2.39e+08<br/> Valid loss: 3.65e+08<br/> Test loss: 3.60+08"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "w = None\n",
    "for i in range(20):\n",
    "    w = train(10000, train_x, train_y, learning_rate=5e-3, initial_weights=w)\n",
    "    print('epoch:', (i+1)*10000, end='   ')\n",
    "    print('Train loss:', loss(predict(w, train_x), train_y), end='   ')\n",
    "    print('Valid loss:', loss(predict(w, valid_x), valid_y))\n",
    "print('Final Model -- Test loss:', loss(predict(w, test_x), test_y))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
